package com.ecoolex.hotel.saas.admin.graphql;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.service.region.Region;
import com.ecoolex.framework.modularize.api.service.region.RegionService;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.hotel.saas.admin.core.AdminConstant;
import com.ecoolex.hotel.saas.entity.Store;
import com.ecoolex.hotel.saas.entity.StoreBrand;
import com.ecoolex.hotel.saas.enums.StoreStatus;
import com.ecoolex.hotel.saas.pojo.EditStoreOneStepDTO;
import com.ecoolex.hotel.saas.pojo.EditStoreThreeStepDTO;
import com.ecoolex.hotel.saas.pojo.EditStoreTwoStepDTO;
import com.ecoolex.hotel.saas.pojo.QueryStoreDTO;
import com.ecoolex.hotel.saas.ws.StoreService;

@GraphQL2Module(type = Type.Admin, description = "商户")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_PROJECT_KEY,
	key = StoreGraphql.AUTH,
	name = "商户管理",
	remark = "商户管理")
public class StoreGraphql {

	public static final String AUTH = AdminConstant.AUTH_PROJECT_KEY + "-STORE";
	
	private static final String AUTH_GET = AUTH + "-GET";
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	private static final String AUTH_EDIT = AUTH + "-EDIT";
	
	private static final String AUTH_DEL = AUTH + "-DEL";
	
	private static final String AUTH_ONLINE = AUTH + "-ONLINE";
	
	private static final String AUTH_OFFLINE = AUTH + "-OFFLINE";
	
	@Autowired
	private StorageService storageService;
	
	@Autowired
	private RegionService regionService;
	
	@Reference
	private StoreService service;
	
	@TypeField(type = Store.class, field = "brand", description = { "品牌" })
	public StoreBrand brand(@Source Store store) {
		return service.getStoreBrand(store.getBrandId());
	}
	
	@TypeField(type = Store.class, field = "logo", description = { "logo" })
	public StorageInfo logo(@Source Store store) {
		return storageService.get(store.getLogo());
	}

	@TypeField(type = Store.class, field = "serviceQrCode", description = { "客服二维码" })
	public StorageInfo serviceQrCode(@Source Store store) {
		return storageService.get(store.getServiceQrCode());
	}
	
	@TypeField(type = Store.class, field = "businessLicense", description = { "营业执照" })
	public StorageInfo businessLicense(@Source Store store) {
		return storageService.get(store.getBusinessLicense());
	}
	
	@TypeField(type = Store.class, field = "organizationCodeImg", description = { "组织机构代码证" })
	public StorageInfo organizationCodeImg(@Source Store store) {
		return storageService.get(store.getOrganizationCodeImg());
	}
	
	@TypeField(type = Store.class, field = "taxRegistration", description = { "税务登记证" })
	public StorageInfo taxRegistration(@Source Store store) {
		return storageService.get(store.getTaxRegistration());
	}
	
	@TypeField(type = Store.class, field = "identityFrontImage", description = { "法人身份证正面" })
	public StorageInfo identityFrontImage(@Source Store store) {
		return storageService.get(store.getIdentityFrontImage());
	}
	
	@TypeField(type = Store.class, field = "identityBackImage", description = { "法人身份证反面" })
	public StorageInfo identityBackImage(@Source Store store) {
		return storageService.get(store.getIdentityBackImage());
	}
	
	@TypeField(type = Store.class,field = "registerRegion",description = { "区域","注册地址" })
	public Region region(@Source Store store) {
		return regionService.get(store.getRegisterCityId());
	}
	
	@TypeField(type = Store.class, field = "canEdit", description = { "是否能编辑" })
	public Boolean canEdit(@Source Store store, AdminMemberAuthority user) {
		return user.auth(AUTH_EDIT);
	}

	@TypeField(type = Store.class, field = "canDel", description = { "是否能删除" })
	public Boolean canDel(@Source Store store, AdminMemberAuthority user) {
		return user.auth(AUTH_DEL) && (Check.eq(store.getStatus(), StoreStatus.EDITING.real())
			|| Check.eq(store.getStatus(), StoreStatus.EDITED.real()));
	}

	@TypeField(type = Store.class, field = "canOffline", description = { "是否能下线" })
	public Boolean canOffline(@Source Store store, AdminMemberAuthority user) {
		return user.auth(AUTH_OFFLINE) && (Check.eq(store.getStatus(), StoreStatus.ONLINE.real()));
	}

	@TypeField(type = Store.class, field = "canOnline", description = { "是否能上线" })
	public Boolean canOnline(@Source Store store, AdminMemberAuthority user) {
		return user.auth(AUTH_ONLINE) && Check.eq(store.getStatus(), StoreStatus.EDITED.real());
	}
	
	@QueryField(field = "storeList", description = { "商户列表" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询商户列表")
	public Pagination<Store> queryStore(@NonNull QueryStoreDTO query, @NonNull Page page, AdminMemberAuthority user) {
		user.assertAuth(AUTH_QUERY);
		return service.queryStore(query, null, page);
	}

	@QueryField(field = "store", description = { "商户详情" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取商户详情")
	public Store getStoreById(@NonNull Integer storeId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return service.getStore(storeId);
	}
	
	@MutationField(field = "editStore",description = { "编辑商户","每一步传递相应的参数对象, 默认传null" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑商户")
	public Store updateStoreStep(EditStoreOneStepDTO one, EditStoreTwoStepDTO two, EditStoreThreeStepDTO three, AdminMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		if (Check.notNull(one)) {
			return service.updateStoreStep(one, user.userName());
		} else if (Check.notNull(two)) {
			return service.updateStoreStep(two, user.userName());
		} else if (Check.notNull(three)) {
			return service.updateStoreStep(three, user.userName());
		}
		Assert.throwVerifyException("没有步数据");
		return null;
	}
	
	@MutationField(field = "delStore", description = { "删除商户" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除商户")
	public Boolean deleteStore(@NonNull Integer storeId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		Store store = service.getStore(storeId);
		Assert.isTrue(Check.notNull(store), ResultCode.VERIFY.build(1), "商户不存在");
		Assert.isTrue(Check.notEq(store.getStatus(), StoreStatus.ONLINE.real()),
			ResultCode.VERIFY.build(2),
			"上线状态无法删除");
		return service.delStore(store, user.userName());
	}

	@MutationField(field = "onlineStore", description = { "上线商户" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ONLINE, name = "上线商户")
	public Store onlineStore(@NonNull Integer storeId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_ONLINE);
		Store store = service.getStore(storeId);
		Assert.isTrue(Check.notNull(store), ResultCode.VERIFY.build(1), "商户不存在");
		Assert.isTrue(Check.eq(store.getStatus(), StoreStatus.EDITED.real()),
			ResultCode.VERIFY.build(1),
			"商户必须是编辑完成状态");
		return service.onlineStore(store, user.userName());
	}

	@MutationField(field = "offlineStore", description = { "下线商户" })
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_OFFLINE, name = "下线商户")
	public Store offlineStore(@NonNull Integer storeId, AdminMemberAuthority user) {
		user.assertAuth(AUTH_OFFLINE);
		Store store = service.getStore(storeId);
		Assert.isTrue(Check.notNull(store), ResultCode.VERIFY.build(1), "商户不存在");
		Assert.isTrue(Check.eq(store.getStatus(), StoreStatus.ONLINE.real()), ResultCode.VERIFY.build(1), "商户必须是上线状态");
		//TODO 请解除优惠券关联商户数据, 再进行下线

		return service.offlineStore(store, user.userName());
	}
	
	@MutationField(field = "uploadStoreLogo", description = { "上传商户Logo" })
	public StorageInfo uploadStoreLogo(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("Store", "Logo");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}

	@MutationField(field = "uploadServiceQrCode", description = { "上传客服二维码" })
	public StorageInfo uploadServiceQrCode(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
			user.notAuthority();
		}
		UploadSource uploadSource = new UploadSource("Store", "ServiceQrCode");
		UploadLimit uploadLimit = new UploadLimit();
		uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
		uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

		return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadBusinessLicense", description = { "上传商户营业执照" })
	public StorageInfo uploadBusinessLicense(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("Store", "BusinessLicense");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(20));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadOrganizationCodeImg", description = { "上传组织机构代码证" })
	public StorageInfo uploadOrganizationCodeImg(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("Store", "OrganizationCodeImg");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadTaxRegistration", description = { "上传税务登记证" })
	public StorageInfo uploadTaxRegistration(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("Store", "TaxRegistration");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadIdentityFrontImage", description = { "上传法人身份证正面" })
	public StorageInfo uploadIdentityFrontImage(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("Store", "IdentityFrontImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadIdentityBackImage", description = { "上传法人身份证反面" })
	public StorageInfo uploadIdentityBackImage(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("Store", "IdentityBackImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
}
